home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programmer Power Tools
/
Programmer Power Tools.iso
/
dskutl
/
bootcode.asm
< prev
next >
Wrap
Assembly Source File
|
1986-01-28
|
9KB
|
386 lines
To: INFO-IBMPC@usc-isib.ARPA
Subject: Re: BOOTCODE.ASM
Date: Tue, 28 Jan 86 14:38:52 -0500
From: Dan Grim <grim@huey.udel.EDU>
I have discovered through my own sad experience that BOOTCODE.ASM is
not able to deal with newer DOS partitions that use the 16-bit FAT
format. BOOTCODE.ASM understands DOS with 12-bit FAT's (ID byte = 1)
and Xenix (ID byte = 2). DOS with 16-bit FAT's has an ID byte = 4
which BOOTCODE doesn't recognize. The fix is trivial: simply change
the line following the label 'lddos' from
mov al,1 ;id for dos
to
mov al,4 ;id for dos with 16-bit FAT's
Of course, once you do that BOOTCODE won't handle 12-bit FAT DOS any
longer.
Dan
ORIGINAL CODE IS AS FOLLOWS:
page 60,132
title Write prompting boot to hard disk
;
; This program will write a new boot sector to drive C:
; that prompts whether you wish to boot xenix
; or dos:
;
; X=Xenix, D=Dos
;
; The reply is the one character first initial of the system.
;
; This program is written as a .com file so it should be assembled
; and linked, ignoring the missing stack segment message from the linker.
; It should then be converted to a com file with exe2bin.
;
;
; MASM BOOTCODE,,,;
; LINK BOOTCODE;
; EXE2BIN BOOTCODE.EXE BOOTCODE.COM
; ERASE BOOTCODE.EXE
;
; Now the program is ready to run. It produces a message at the
; start telling you what it is going to do, to allow aborting before
; touching your hard disk.
;
; The boot only runs on an AT or a pc with Enhanced Graphics Adapter,
; since it uses subfunction 19 of the video call, Write String.
;
; Distribution of this program in any way is acceptable to me.
;
; W.D. Cagle 75206,2701
;
code segment 'code'
assume cs:code,ds:code
video equ 10h
kbd equ 16h
diskio equ 13h
basic equ 18h
dos equ 21h
;
cr equ 0dh
lf equ 0ah
base equ $
bootloc equ 7c00h
;
org 100h
writboot proc near
jmp start ;jump around constants
bootsec proc near
bcode equ $
adjust equ 600h-103h ;stupid adjustment
cli ;disable interrupts
xor ax,ax ;clear
mov ss,ax ;place in stack segment
mov sp,offset bootloc ;get my address
mov si,sp ;place in source
push ax ;
pop es ;put in extra segment
push ax ;now for ds
pop ds ;load it
sti ;enable interrupts
cld ;make move direction positive
mov di,600h ;place to move to
mov cx,100h ;how many words to move
rep movsw ;move it
mov ax,offset relboot+adjust ;this gets rid of exe2bin
push ax ;wanting a fixup, cs=0 anyway
ret
;
relboot:
mov byte ptr p1+adjust,0
mov byte ptr p2+adjust,0
mov byte ptr p3+adjust,0
mov byte ptr p4+adjust,0
wrprmpt:
mov si,offset msg4+adjust ;go ask question
xor ch,ch ;clear
lodsb ;get message length
mov cl,al ;to cl
mov ax,1301h ;say write message
mov bx,7 ;use normal attribute
sub dx,dx ;row 0 col 0
mov bp,si ;get location of message
int video ;print message
mov al,' ' ;blank out response
mov cx,1 ;1 byte
mov ah,10 ;say write char only
int video ;do it
mov ah,0 ;get keyboard input
int kbd
and al,7fh-20h ;make upper case
push ax
mov ah,10 ;say write char
mov cx,1 ;1 byte
int video ;let 'em see what they typed
pop ax
cmp al,'D' ;want dos?
je lddos ;yes
cmp al,'X' ;want xenix
je xenix ;yes
jmp wrprmpt ;ask again
;
lddos:
mov al,1 ;id for dos
mov si,offset dosnm+adjust ;dos name
jmp short gotact1 ;continue
;
xenix:
mov al,2 ;id for xenix
mov si,offset xenixnm+adjust ;xenix name
gotact1:
mov di,offset msg5nm+adjust ;put name in message
mov cx,6 ;length of name
cld ;positive direction
rep movsb ;move it
mov bl,4 ;max 4 to search
mov si,offset parttbl+adjust ;point to first entry
getpart_a:
cmp byte ptr[si+4],al ;is this the one
je gotact2 ;yes
add si,16 ;to next
dec bl ;count em
jnz getpart_a ;not end yet
mov si,offset msg5+adjust ;
xor ch,ch ;clear
lodsb ;get message length
mov cl,al ;to cl
mov ax,1301h ;say write message
mov bx,7 ;use normal attribute
sub dx,dx ;row 0 col 0
mov bp,si ;get location of message
int video ;print message
lupe1: jmp lupe1 ;and hang
;
gotact2:
mov byte ptr[si],80h ;say active
push si
push bx
mov ax,0301h
mov bx,600h
mov cx,1
mov dx,80h
int diskio
pop bx
pop si
;
gotact:
mov dx,[si] ;drive in dh, head in dl
mov cx,[si+2] ;get track in ch, sector in cl
mov bp,si ;save indicator
;
;
finis:
mov di,5 ;retry count
rdboot:
mov bx,bootloc ;location for boot
mov ax,0201h ;say read 1 sector
push di ;
int diskio ;go do it
;
pop di ;
jnc goodrd ;good read
;
xor ax,ax ;say recalibrate
int diskio ;do it
dec di ;count retries
jnz rdboot ;continue trying
mov si,offset msg2+adjust ;point to bad disk message
wrmsg:
xor ch,ch ;clear
lodsb ;get message length
mov cl,al ;to cl
mov ax,1301h ;say write message
mov bx,7 ;use normal attribute
sub dx,dx ;row 0 col 0
mov bp,si ;get location of message
int video ;print message
lupe: jmp lupe ;and hang
;
goodrd:
mov si,offset msg3+adjust ;point to no boot rec msg
cmp word ptr bootsig,0aa55h ;see if boot signature
jne wrmsg
;
mov si,bp ;restore partition table pointer
mov ax,offset bootloc ;where partition boot start
push ax
ret
;
;
msg2 db lmsg2,'Error loading operating system'
lmsg2 equ ($-msg2)-1
msg3 db lmsg3,'Missing operating system'
lmsg3 equ ($-msg3)-1
msg4 db lmsg4,'Enter X=Xenix, D=DOS '
lmsg4 equ ($-msg4)-1
msg5 db lmsg5,'Cannot find '
msg5nm db 'xxxxx'
lmsg5 equ ($-msg5)-1
dosnm db 'DOS '
xenixnm db 'XENIX'
parttbl equ byte ptr bcode+1beh
p1 equ bcode+1beh
;
p2 equ p1+16
;
p3 equ p2+16
;
p4 equ p3+16
;
signat equ p4+16
bootsig equ base+7dfeh
org bcode+512
bootsec endp
diskbuf db 512 dup(?)
helloms db cr,lf
db 'Bootwriter - This program will read the boot sector',cr,lf
db 'from disk C: and merge the partition table in with',cr,lf
db 'the boot program which follows and write it all back',cr,lf
db 'out to disk C: overlaying what is there. The resultant',cr,lf
db 'boot program will prompt for the desired system when',cr,lf
db 'booting, Xenix or Dos.',cr,lf
db cr,lf
db 'The original boot program will be saved in a file named',cr,lf
db 'IBMBOOT.SVE in the default directory.',cr,lf
db cr,lf
db 'If you do not wish to do this, you should control-c out',cr,lf
db 'at the prompt.',cr,lf
db 'Reply with the enter key to continue, or control-c to stop $'
crlf db cr,lf,'$'
ibmboot db 'IBMBOOT.SVE',0
okmsg db 'Boot sector updated',cr,lf,'$'
ermsg1 db 'Error reading boot sector',cr,lf,'$'
ermsg2 db 'Cannot open save file',cr,lf,'$'
ermsg3 db 'Cannot write save file',cr,lf,'$'
ermsg4 db 'Cannot close save file',cr,lf,'$'
ermsg5 db 'Cannot write boot sector, boot sector creamed',cr,lf,'$'
boothdl dw 0
;
start:
mov dx,offset helloms ;point to signon message
mov ah,9 ;print string
int dos ;say print it
;
rdcns: mov ah,0ch ;clear kb buffer
mov al,1 ;read keyboard input
int dos ;do it
cmp al,cr ;enter key?
jne rdcns ;wait till it is
;
; well, we continue
;
mov dx,offset crlf ;echo the return
mov ah,9
int dos ;write to console
;
mov si,5 ;set up for 5 retries
rddsk:
push si ;save retry counter
mov ah,2 ;say read disk
mov al,1 ;1 sector
mov bx,offset diskbuf ;point to buffer
mov ch,0 ;say cylinder 0
mov cl,1 ;say sector 1
mov dh,0 ;say track 0
mov dl,80h ;say hard drive 0
int diskio ;do the io
pop si
jnc rdok ;good read
dec si ;any more tries?
jnz rddsk ;yes, try again
mov dx,offset ermsg1 ;point to trouble message
mov ah,9 ;say console write
int dos ;can't read boot sector
mov ah,4ch ;say terminate
mov al,1 ;error return code
int dos ;does not return
;
rdok:
mov dx,offset ibmboot ;get file name
mov ah,3ch ;say create it
sub cx,cx ;zero attribute
int dos
jnc openok ;file opened
mov dx,offset ermsg2 ;can't open save file
mov ah,9
int dos ;tell 'em
mov ah,4ch ;say terminate
mov al,2 ;reason
int dos ;
;
openok:
mov boothdl,ax ;save handle
mov bx,ax ;and put in bx
mov ah,40h ;say write to file
mov dx,offset diskbuf ;get location
mov cx,512 ;say 1 sector
int dos ;ask to have it done
jnc wrtok ;good write
mov dx,offset ermsg3 ;can't write to save file
mov ah,9
int dos ;tell 'em
mov ah,4ch ;say terminate
mov al,3 ;reason
int dos ;
;
wrtok:
mov ah,3eh ;say close file
mov bx,boothdl ;
int dos ;
jnc closok ;closed ok
mov dx,offset ermsg4 ;can't close save file
mov ah,9
int dos ;tell 'em
mov ah,4ch ;say terminate
mov al,4 ;reason
int dos ;
;
closok:
push si
mov si,offset diskbuf+1beh ;start of partition table
mov di,offset bootsec+1beh ;ditto for new sector
cld ;make direction positive
mov cx,4*16+2 ;how many bytes to move
rep movsb ;move em
mov si,5 ;5 retries
wrtboot:
push si
mov ah,3 ;say write to disk
mov al,1 ;say 1 sector
mov bx,offset bootsec ;point to sector to write
mov cx,1 ;say sector 1
mov dx,80h ;
int diskio ;do the io
pop si
jnc updok ;good write to boot sector
dec si ;count retries
jnz wrtboot ;try again
;
mov dx,offset ermsg5 ;can't write boot sector file
mov ah,9
int dos ;tell 'em
mov ah,4ch ;say terminate
mov al,5 ;reason
int dos ;
;
updok:
mov dx,offset okmsg ;say we did it
mov ah,9
int dos ;tell 'em
mov ah,4ch ;say terminate
mov al,0 ;good return code
int dos ;
writboot endp
;
; new boot code follows
;
code ends
end writboot